package com.tebiecloud.common.utils;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.LinkedList;
import java.util.List;

import lombok.extern.slf4j.Slf4j;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;

/**
 * Json工具类，参考 http://www.cnblogs.com/a757956132/p/5555834.html
 * @author xiaoc
 */
@Slf4j
public class JsonUtils {

	/**
	 * 对象转json字符串
	 * @param obj
	 * @return
	 */
	public static String Obj2Str(Object obj) {
		try {
			return JSON.toJSONString(obj);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return null;
	}

	/**
	 * 字符串转json
	 * @param jsonStr
	 * @return
	 */
	public static JSONObject str2Json(String jsonStr) {
		if(jsonStr != null) {
			try {
				return JSON.parseObject(jsonStr);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		return null;
	}

	/**
	 * 字符串转jsonarry
	 * @param jsonStr
	 * @return
	 */
	public static JSONArray str2JSONArry(String jsonStr) {
		try {
			return JSONArray.parseArray(jsonStr);
		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}

	/**
	 * xml格式转json
	 * @param xmlStr
	 * @return
	 */
	public static JSONObject xml2Json(String xmlStr) {
		if (!StringUtils.isEmpty(xmlStr)) {
			try {
				xmlStr = xmlStr.replaceAll("\\\n", "");
				byte[] xml = xmlStr.getBytes("UTF-8");
				JSONObject json = new JSONObject();
				InputStream is = new ByteArrayInputStream(xml);
				SAXBuilder sb = new SAXBuilder();
				Document doc = sb.build(is);
				Element root = doc.getRootElement();
				json.put(root.getName(), iterateElement(root));

				return json;
			} catch (Exception e) {
				log.info("xiaoc>> xml2json failed, xmlStr: " + xmlStr);
				e.printStackTrace();
			}
		}

		return null;
	}

	/**
	 * 遍历元素返回json
	 * @param element
	 * @return
	 */
	private static JSONObject iterateElement(Element element) {
		List<Element> node = element.getChildren();
		JSONObject obj = new JSONObject();
		List list = null;
		for (Element child : node) {
			list = new LinkedList();
			String text = child.getTextTrim();
			if (StringUtils.isBlank(text)) {
				if (child.getChildren().size() == 0) {
					continue;
				}
				if (obj.containsKey(child.getName())) {
					list = (List) obj.get(child.getName());
				}
				list.add(iterateElement(child)); //遍历child的子节点
				obj.put(child.getName(), list);
			} else {
				if (obj.containsKey(child.getName())) {
					Object value = obj.get(child.getName());
					try {
						list = (List) value;
					} catch (ClassCastException e) {
						list.add(value);
					}
				}
				if (child.getChildren().size() == 0) { //child无子节点时直接设置text
					obj.put(child.getName(), text);
				} else {
					list.add(text);
					obj.put(child.getName(), list);
				}
			}
		}
		return obj;
	}

	/**
	 * 字符串转bean类
	 * @param jsonStr
	 * @param cls
	 * @return
	 */
	public static <T> T str2Bean(String jsonStr, Class<T> cls) {
		T obj = null;

		if(jsonStr != null) {
			try {
				obj = JSON.parseObject(jsonStr, cls);
			} catch (Exception e) {
				e.printStackTrace();
				log.info("xiaoc>> jsonStr: {}", jsonStr);
			}
		}

		return obj;
	}

	/**
	 * 字符串转bean类
	 * @param jsonArrStr
	 * @param cls
	 * @param <T>
	 * @return
	 */
	public static <T> List<T> str2ListBean(String jsonArrStr, Class<T> cls) {
		List<T> obj = null;
		try {
			obj = JSONArray.parseArray(jsonArrStr, cls);
		} catch (Exception e) {
			e.printStackTrace();
			log.info("xiaoc>> jsonArrStr: {}", jsonArrStr);
		}

		return obj;
	}

	/**
	 * 字符串转Object对象
	 * @param jsonObj
	 * @return
	 */
	public static <T> T str2Object(String jsonObj, TypeReference<T> type) {
		T obj = null;
		try {
			obj = JSONArray.parseObject(jsonObj, type);
		} catch (Exception e) {
			e.printStackTrace();
			log.info("xiaoc>> jsonObj: {}", jsonObj);
		}

		return obj;
	}

	public static void main(String[] args) {
		String s = "{\"Id\":2,\"name\":\"fds\"}";
		JSONObject jsonObj = str2Json(s);

		System.out.println(jsonObj.get("Id"));
	}
}
